<?php
/**
 * Created by PhpStorm.
 * User: BlueIdeaLirui
 * Date: 2019-11-27
 * Time: 14:04
 */

namespace business\base\services\queues;

use business\base\caches\DataCache;
use business\search\models\UnindexSearchDataModel;
use common\queue\QueueConstants;
use common\utils\DateTimeUtils;

/**
 * 供应商调度基础服务
 * Class SupplierCronService
 * @package business\bigdata\services
 */
abstract class BaseService
{
    /**
     * @var string 任务开始时间
     */
    protected $jobCreatedTime;

    /**
     * @var int 去大数据供应商库每次查询取出的最大数量
     */
    const MAX_COUNT_PER_QUERY = 100;

    /**
     * @var int 每次更新索引的最大document数
     */
    const MAX_COUNT_PER_INDEX = 1000;

    /**
     * @var int 增量更新的时间定义：e.g. -1 表示前一天变更的数据属于增量
     */
    const INCREMENT_DATE_INTERVAL = -1;

    /**
     * 增量方式更新时: 通过last_modified_time查找时，默认查找离当前时间多少分钟内的变更项
     */
    const DEFAULT_INCREMENT_TIME = '3';

    /**
     * 暂停时间
     */
    const MICRO_SECOND = 500;

    /**
     * 分隔符
     */
    const DELIMITER = '#s#';

    /**
     * 回调方法
     * @var
     */
    protected $callbackMethod;

    /**
     * 基础服务构造器
     * SupplierBaseService constructor.
     */
    public function __construct()
    {
        $this->jobCreatedTime = strval(date('YmdHis', DateTimeUtils::time()));
        $this->callbackMethod = function($updateData){
            print "批量数据执行完成！\n";
        };
    }

    /**
     * 保存非合规索引数据
     * @param $type
     * @param $title
     * @param $key
     * @param $reason
     */
    public function saveUnIndexData($type, $title, $key, $reason)
    {
        $model = new UnindexSearchDataModel();
        $model->type = $type;
        $model->title = $title;
        $model->key = $key;
        $model->reason = $reason;
        $model->created_time = DateTimeUtils::now();
        $model->save();
    }

    /**
     * 更新数据索引
     * @param $needUpdateIndexArrays
     * @param $action
     * @param $jobCreatedTime
     */
    protected function updateDataIndex
    (
        $needUpdateIndexArrays = [],
        $action,
        $jobCreatedTime = null
    ) {
        if (!empty($needUpdateIndexArrays) && !empty($action)) {
            $method = $action . 'index';
            $indexStartTime = explode(' ', microtime());

            if (is_callable([$this, $method])) {
                call_user_func_array([$this, $method], [$needUpdateIndexArrays, $jobCreatedTime]);
            }

            $indexEndTime = explode(' ', microtime());
            $indexThisTime = $indexEndTime[0] + $indexEndTime[1] - ($indexStartTime[0] + $indexStartTime[1]);
            $indexThisTime = round($indexThisTime, 3);
            $count = 0;
            is_array($needUpdateIndexArrays) && $count = count($needUpdateIndexArrays);
            echo "  " .$action  . "索引数据个数" . $count . " 条供应商数据 " . PHP_EOL;
            echo "  " . $action . "索引耗时：" . $indexThisTime . " 秒" . PHP_EOL;
        }
    }

    /**
     * 数据是否存在缓存中
     * @param string $cacheKey
     * @return bool
     */
    protected function existInCache
    (
        $queueCacheName = '',
        $cacheKey = ''
    ) {
        $data = (new DataCache())->getRecordByHash(
            $queueCacheName, $cacheKey);

        return !empty($data)
            ? true : false;
    }

    /**
     * uuid 唯一序列码
     * @param string $prefix
     * @return string
     */
    protected function uuid($prefix = '')
    {
        $chars = md5(uniqid(mt_rand(), true));
        $uuid  = substr($chars,0,8) . '-';
        $uuid .= substr($chars,8,4) . '-';
        $uuid .= substr($chars,12,4) . '-';
        $uuid .= substr($chars,16,4) . '-';
        $uuid .= substr($chars,20,12);
        return $prefix . $uuid;
    }

    /**
     * 重发机制
     * @param string $queueName
     * @param string $module
     * @param string $title
     * @throws \yii\base\InvalidConfigException
     */
    public function processResend
    (
        $queueName = '',
        $module = '',
        $title = ''
    ) {
        /** @var iQueue $queue */
        $queue = \yii::$app->iQueue->createClient($queueName);

        $queueCacheName = $module . '-' . QueueConstants::QUEUE_CHACHE_NAME;
        $dataCache = new DataCache();
        $keys = $dataCache->getKeys($queueCacheName . '*');
        $i = 0;
        if ($keys) {
            foreach ($keys as $key) {
                list($prefix, $name) = explode(':', $key);
                $values = $dataCache->getRecordByHash($prefix, $name);
                $createdDate = strtotime($values['created_on']);
                $currentDate = DateTimeUtils::time();
                if (DateTimeUtils::getTimeDiff($currentDate, $createdDate) >= 2) {
                    $data  = [
                        'source' => $values['source']
                        , 'values' => $values['values']
                        , 'uuid' => $values['uuid']
                        , 'created_on' => $values['created_on']
                    ];
                    $message = md5(serialize($data));
                    $queue->sendMsg($message, function ($msgBody) use($i, $title) {
                        echo $title . '-已插入队列比例: ' . ($i + 1) . PHP_EOL;
                    });
                    $i++;
                }
                usleep(self::MICRO_SECOND);
            }
        }
    }

    /**
     * 清除已经消费过的队列数据
     * @param string $module
     * @throws \yii\base\InvalidConfigException
     */
    public function processclearConsumerQueue($module = '')
    {
        $dataCache = new DataCache();
        $queueCacheName = $module . '-' . QueueConstants::QUEUE_CHACHE_NAME;
        $keys = $dataCache->getKeys('consumer-' . $queueCacheName . '*');
        $i = 0;
        if ($keys) {
            foreach ($keys as $key) {
                $data = unserialize($dataCache->getValue($key));
                $createdDate = strtotime($data['created_on']);
                $currentDate = DateTimeUtils::time();
                if (DateTimeUtils::getTimeDiff($currentDate, $createdDate) >= 2) {
                    list($prefix, $name) = explode(':', $key);
                    $dataCache->delRecordByHash($prefix, $name);
                    echo '已清除消费过的队列: ' . ($i + 1) . PHP_EOL;
                    $i++;
                }
                usleep(self::MICRO_SECOND);
            }
        }
    }
}
